package com.github.ilioili.justdoit.util;

import java.util.Calendar;
import java.util.Date;

/**
 * Created by hantuo on 16/5/12.
 */
public class DateRepeatUtil {


    public static boolean matchToday(int repeatFlag) {
        return matchTheDay(repeatFlag, Calendar.getInstance().getTime());
    }

    public static boolean matchTheDay(int repeatFlag, Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (getBit(repeatFlag, 31)) {//Monthly
            return getBit(repeatFlag, calendar.get(Calendar.DAY_OF_MONTH) - 1);
        } else {
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            int bitPosition = dayOfWeek - 2;
            if (bitPosition == -1) bitPosition = 6;
            return getBit(repeatFlag, bitPosition);
        }
    }

    public static boolean matchTheDay(int repeatFlag, long time){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        if (getBit(repeatFlag, 31)) {//Monthly
            return getBit(repeatFlag, calendar.get(Calendar.DAY_OF_MONTH) - 1);
        } else {
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            int bitPosition = dayOfWeek - 2;
            if (bitPosition == -1) bitPosition = 6;
            return getBit(repeatFlag, bitPosition);
        }
    }

    /**
     * 从周一到周日 分别为1，2，3，4，5，6，7
     *
     * @param repeatFlag the updated repeatFlag
     * @param dayOfWeek
     * @param b
     * @return
     */
    public static int getWeeklyRepeatFlag(int repeatFlag, int dayOfWeek, boolean b) {
        repeatFlag = setBit(repeatFlag, 31, false);
        int bitPosition = dayOfWeek - 1;
        repeatFlag = setBit(repeatFlag, bitPosition, b);
        return repeatFlag;
    }

    public static int getWeeklyAlldayFlag(boolean b) {
        int repeatFlag = 0;
        for (int i = 1; i < 8; i++) {
            repeatFlag = getWeeklyRepeatFlag(repeatFlag, i, b);
        }
        return repeatFlag;
    }

    public static int getMonthAlldayFlag(boolean b) {
        int repeatFlag = 0;
        for (int i = 0; i < 31; i++) {
            repeatFlag = getMonthlyRepeatFlag(repeatFlag, i, b);
        }
        return repeatFlag;
    }

    /**
     * @param repeatFlag the updated repeatFlag
     * @param dayOfMonth 从1到31
     * @param b
     * @return
     */
    public static int getMonthlyRepeatFlag(int repeatFlag, int dayOfMonth, boolean b) {
        repeatFlag = setBit(repeatFlag, 31, true);
        repeatFlag = setBit(repeatFlag, dayOfMonth - 1, b);
        return repeatFlag;
    }

    public static boolean isWeeklyRepeat(int repeatFlag) {
        return !getBit(repeatFlag, 31);
    }

    /**
     * @param dayOfWeek  从周一到周日 分别为1，2，3，4，5，6，7
     * @param repeatFlag
     * @return
     */
    public static boolean isDayOfWeekMatch(int dayOfWeek, int repeatFlag) {
        dayOfWeek--;
        return getBit(repeatFlag, dayOfWeek);
    }


    /**
     * @param dayOfMonth
     * @param repeatFlag
     * @return
     */
    public static boolean isDayOfMonthMatch(int dayOfMonth, int repeatFlag) {
        return getBit(repeatFlag, dayOfMonth);
    }

    /**
     * @param dayOfMonth 1~31
     * @param repeatFlag
     * @return
     */
    public static boolean isMonthlyRepeat(int dayOfMonth, int repeatFlag) {
        repeatFlag--;
        return getBit(repeatFlag, 31);
    }

    private static int setBit(int repeatFlag, int index, boolean b) {
        if (b) {
            int mask = 1 << index;
            repeatFlag |= mask;
        } else {
            int mask = 1 << index;
            mask ^= -1;
            repeatFlag &= mask;
        }
        return repeatFlag;
    }

    private static boolean getBit(int repeatFlag, int index) {
        int mask = 1 << index;
        return ((repeatFlag & mask) >>> index) == 1;
    }


}
